package yui.comn.hub.extension.crypt;

import java.io.IOException;
import java.lang.reflect.Type;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdviceAdapter;

import com.fasterxml.jackson.databind.ObjectMapper;

import yui.comn.hub.annotation.Crypt;
import yui.comn.hub.extension.config.HubExtensionProperties;
import yui.comn.hub.model.CryptMode;
import yui.comn.hub.model.CryptType;

@ControllerAdvice
@EnableConfigurationProperties(HubExtensionProperties.class)
public class DecryptRequestBodyAdviceAdapter extends RequestBodyAdviceAdapter {

	@Autowired
	private HubExtensionProperties properties;
	
	protected ObjectMapper objectMapper = new ObjectMapper();
	
	@Override
	public boolean supports(MethodParameter methodParameter, Type targetType,
			Class<? extends HttpMessageConverter<?>> converterType) {
		if (properties.isCrypt()) {
			if (properties.isDecrypt()) {
				return Boolean.TRUE;
			}
			Crypt crypy = methodParameter.getMethodAnnotation(Crypt.class);
			if (null != crypy && crypy.decrypt()) {
				return Boolean.TRUE;
			}
		}
		return Boolean.FALSE;
	}

	@Override
	public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter methodParameter, Type targetType,
			Class<? extends HttpMessageConverter<?>> converterType) throws IOException {
		
		CryptType cryptType = CryptType.get(properties.getCryptType());
		CryptMode cryptMode = CryptMode.get(properties.getCryptMode());
		
		Crypt crypy = methodParameter.getMethodAnnotation(Crypt.class);
		if (null != crypy) {
			if (!crypy.decrypt()) {
				return super.beforeBodyRead(inputMessage, methodParameter, targetType, converterType);
			}
			if (CryptType.NULL != crypy.cryptType()) {
				cryptType = crypy.cryptType();
			}
			if (CryptMode.NULL != crypy.cryptMode()) {
				cryptMode = crypy.cryptMode();
			}
		}
		
		HttpInputMessage him = CryptHandler.handle(inputMessage, cryptType, cryptMode);
        
        return super.beforeBodyRead(him, methodParameter, targetType, converterType);
        
	}

	@Override
	public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
			Class<? extends HttpMessageConverter<?>> converterType) {
		return super.afterBodyRead(body, inputMessage, parameter, targetType, converterType);
	}
	
	

}
